import pybloom_live
from gmpy2 import mpz
from sympy.codegen import Print
from sympy.core.sympify import kernS

from bloom_filter import BloomFilter
import threshold_paillier
from threshold_paillier import multiply_homomorphically, partial_decrypt, gen_coprime
from paillier import keyGeneration, encryption, decryption, encryption_add, generate_prime, rerandomize, \
    encryption_mul_const, generate_random_number



def main():
    # 创建布隆过滤器实例
    client_1_set = [1, 2, 3, 4]
    client_2_set = [5, 2, 6, 4]
    # 修改为 m_bits 和 k_hashes
    bloom_filter_1 = BloomFilter(m_bits=50, k_hashes=3)
    print("Inint-bloom-filter")
    bloom_filter_1.print_bloom_filter()
    # 生成BF1
    for num in client_1_set:
        bloom_filter_1.insert(num)
    print("Insert-bloom-filter")
    bloom_filter_1.print_bloom_filter()
    # 生成IBF1
    bloom_filter_1.invert()
    print("Inint-revert-bloom-filter")
    bloom_filter_1.print_bloom_filter()

    n, λ, v, h = keyGeneration(1024)

    EIBF1 = BloomFilter(m_bits=bloom_filter_1.m_bits, k_hashes=bloom_filter_1.k_hashes)

    # 生成EIBF1
    EIBF1=bloom_filter_1.paillier_encrypt_all(n,h)
    print("EIBF1")
    bloom_filter_1.print_bloom_filter()

    #P2对自己每一个数据进行处理，生成对应的数据位和状态位
    total_encrypted_sum = encryption(mpz(0), n,h)  # 初始化加密结果为 0
    num=[]
    status=[]
    for element in client_2_set:
        for i in range(bloom_filter_1.k_hashes):  # 对每个元素进行三次哈希
            index = bloom_filter_1.hash(element, i+1) % bloom_filter_1.m_bits
            # 获取 EIBF1 index 对应的加密值
            encrypted_value_1 = EIBF1[index]
            # 同态加法
            total_encrypted_sum = encryption_add(n,total_encrypted_sum, encrypted_value_1)
        r1 = generate_random_number(n)
        #生成标志位
        temp1=r1*total_encrypted_sum
        #生成数据位
        temp2=encryption(element,n,h)
        #对标志位和数据位进行随机化
        temp1=rerandomize(temp1,n,h)
        temp2=rerandomize(temp2,n,h)
        #最终传输数据为 标志位+数据位
        temp = encryption_add(n,temp1,temp2)
        #数据位列表
        num.append(temp)
        #标志位列表
        status.append(temp1)
        total_encrypted_sum = encryption(mpz(0), n, h)
    #P1收到P2的数据位和状态位列表，进行2-PSI
    for i in range(len(num)):
        print(f"(status[{i}],num[{i}]) = ",decryption(status[i], λ, n, v),decryption(num[i], λ, n, v))
    result=[]
    for i in range(len(status)):
        if decryption(status[i],λ, n, v) == 0:
            #解密数据位
            result.append(int(decryption(num[i], λ, n, v)))
    print("PSI = ",result)
if __name__ == "__main__":
    main()
